package com.zaozhuang.robot.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.media.Image;
import android.util.Log;

import androidx.camera.core.CameraInfo;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import com.google.common.util.concurrent.ListenableFuture;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CameraManager {
    private final Context mContext;
    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
    private ProcessCameraProvider mCameraProvider;
//    private boolean mIsRobotDevice = true;
    private int mLensFacing;
    private BitmapCallback mBitmapCallback;

    public interface BitmapCallback {
        void onBitmapCaptured(Bitmap bitmap);
        void onError(String error);
    }

    public CameraManager(Context context, int lensFacing) {
        mContext = context;
        mLensFacing = lensFacing;
    }

    public void setBitmapCallback(BitmapCallback callback) {
        mBitmapCallback = callback;
    }

    public void startCamera() {
        ListenableFuture<ProcessCameraProvider> providerFuture = ProcessCameraProvider.getInstance(mContext);
        providerFuture.addListener(() -> {
            try {
                mCameraProvider = providerFuture.get();
                List<CameraInfo> cameraInfoList = mCameraProvider.getAvailableCameraInfos();
                for (int i = 0; i < cameraInfoList.size(); i++) {
                    Log.e("CameraManager cameraInfoList", cameraInfoList.get(i).toString());
                }
                bindCameraUseCases();
            } catch (Exception e) {
                notifyError("Camera initialization failed: " + e.getMessage());
            }
        }, ContextCompat.getMainExecutor(mContext));
    }

    private void bindCameraUseCases() {
        try {
            // 配置图像分析
            ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                    .build();

            imageAnalysis.setAnalyzer(mExecutor, imageProxy -> {
                try {
                    Bitmap bitmap = processImageProxy(imageProxy);
                    if (bitmap != null && mBitmapCallback != null) {
                        mBitmapCallback.onBitmapCaptured(bitmap);
                    }
                } catch (Exception e) {
                    notifyError("Image processing error: " + e.getMessage());
                } finally {
                    imageProxy.close();
                }
            });

            // 选择摄像头
//            int lensFacing = mIsRobotDevice ?
//                    CameraSelector.LENS_FACING_BACK :
//                    CameraSelector.LENS_FACING_FRONT;

            CameraSelector selector = new CameraSelector.Builder()
                    .requireLensFacing(mLensFacing)
                    .build();

            // 绑定生命周期
            mCameraProvider.unbindAll();
            mCameraProvider.bindToLifecycle(
                    (LifecycleOwner) mContext,
                    selector,
                    imageAnalysis
            );

        } catch (Exception e) {
            notifyError("Camera binding failed: " + e.getMessage());
        }
    }

    private Bitmap processImageProxy(ImageProxy imageProxy) {
        // 转换为 Bitmap 并处理旋转
        @SuppressLint("UnsafeOptInUsageError") Image image = imageProxy.getImage();
        if (image == null) return null;

        // YUV 转 Bitmap
        Bitmap bitmap = yuv420ToBitmap(image);

        // 处理设备旋转
        int rotation = imageProxy.getImageInfo().getRotationDegrees();
        return rotateBitmap(bitmap, rotation);
    }

    private Bitmap yuv420ToBitmap(Image image) {
        // 实现 YUV 到 Bitmap 的转换（这里需要完整实现）
        // 示例代码（需补充完整）：
        ByteBuffer yBuffer = image.getPlanes()[0].getBuffer();
        ByteBuffer uBuffer = image.getPlanes()[1].getBuffer();
        ByteBuffer vBuffer = image.getPlanes()[2].getBuffer();

        int ySize = yBuffer.remaining();
        int uSize = uBuffer.remaining();
        int vSize = vBuffer.remaining();

        byte[] nv21 = new byte[ySize + uSize + vSize];
        yBuffer.get(nv21, 0, ySize);
        vBuffer.get(nv21, ySize, vSize);
        uBuffer.get(nv21, ySize + vSize, uSize);

        YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21,
                image.getWidth(), image.getHeight(), null);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 75, out);
        byte[] imageBytes = out.toByteArray();
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    }

    private Bitmap rotateBitmap(Bitmap source, int degrees) {
        if (degrees == 0) return source;
        Matrix matrix = new Matrix();
        matrix.postRotate(degrees);
        return Bitmap.createBitmap(
                source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
    }

    private void notifyError(String error) {
        if (mBitmapCallback != null) {
            mBitmapCallback.onError(error);
        }
    }

    public void shutdown() {
        mExecutor.shutdown();
        if (mCameraProvider != null) {
            mCameraProvider.unbindAll();
        }
    }
}
